﻿using System;
using System.Collections.Generic;
using System.Web.Http;
using SalesSys.Comm.BLL;
using SalesSys.Comm.Utility;
using SalesSys.DAL.Models;
using SalesSys.Service.Sales;
using SalesSys.Site.Models;
using SalesSys.WebCore;
using SalesSys.WebCore.Authorize;
using SalesSys.BLL;
using SalesSys.BLL.Sales;
using System.Net.Http;
using System.IO;
using hlib.IO;
using System.Linq;
using System.Transactions;

namespace SalesSys.Site.Controllers.Api
{
    /// <summary>
    /// 计划单
    /// </summary>
    [RoutePrefix("api/Order")]
    public class OrderController : BaseApiController
    {
        private SalesSys.BLL.Sales.OrderBLL bll = BllFactory.GetBll<SalesSys.BLL.Sales.OrderBLL>();
        private LockOrderBLL lockBLL = BllFactory.GetBll<LockOrderBLL>();
        private EmployeeBLL employeeBLL = BllFactory.GetBll<EmployeeBLL>();
        private CustomerBLL customerBLL = BllFactory.GetBll<CustomerBLL>();
        private AccountBLL accountBLL = BllFactory.GetBll<AccountBLL>();
        private DistrictBLL districtBLL = BllFactory.GetBll<DistrictBLL>();
        private ProviderBLL providerBll = BllFactory.GetBll<ProviderBLL>();
        private DepotCommodityRecordBLL depotCommodityRecordBLL = BllFactory.GetBll<DepotCommodityRecordBLL>();
        private CommodityBLL commodityBLL = BllFactory.GetBll<CommodityBLL>();
        private CommodityInfoBLL commodityInfoBLL = BllFactory.GetBll<CommodityInfoBLL>();
        private IDirectSale saleSvc = new SalesSvc();
        private CustomerBalanceBLL customerBalanceBll = new CustomerBalanceBLL();

        /// <summary>
        /// 计划单列表
        /// </summary>
        /// <param name="page">分页</param>
        /// <param name="rows">每页条数</param>
        /// <param name="state">状态</param>
        /// <param name="keyword">关键字</param>
        /// <param name="customerId">客户编号</param>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        [Route("List")]
        public ViewDto<IEnumerable<Order>> Get(int page, int rows, OrderState? state = null, string keyword = null, Guid? customerId = null, DateTime? startTime = null, DateTime? endTime = null)
        {
            var empId = ClientHelper.ClientInfo.Id;
            var re = bll.Select(keyword, state, customerId, startTime, endTime, page, rows);
            var dto = new ViewDto<IEnumerable<Order>>();
            dto.Data = re.Value;
            dto.Total = re.Key;
            dto.Page = page;
            dto.Rows = rows;
            return dto;
        }

        /// <summary>
        /// 计划单详情
        /// </summary>
        /// <param name="id">订单编号</param>
        [Route("Detail")]
        public Order Get(Guid id)
        {
            var result = bll.Details(id);
            //查询当前账户当前客户经理当前客户的余额
            if (result!=null)
            {
                result.Account.Amount = customerBalanceBll.GetAccountAmount(result.Customer.Id, result.Creater.Id, result.Account.Id);
            }
            return result;
        }

        /// <summary>
        /// 创建计划单
        /// </summary>
        /// <param name="model">计划单实体类</param>
        [Route("Add")]
        [ApiUserRoleAuth(RolesConst.ClientManager, RolesConst.Admin)]
        public IResultState Add(OrderDto model)
        {
            using (var tran = new TransactionScope())
            {
                var order = model.ToEntity();
                order.Creater = employeeBLL.Details(ClientHelper.ClientInfo.Id);
                order.Customer = customerBLL.Details(model.CustomerId);
                // if (order.Creater.Id != order.Customer.ClientManager.Id)
                //  return ReState.ArgError.Create("请选择您已报备的客户");
                order.Provider = providerBll.Details(model.ProviderId);
                order.Account = accountBLL.Details(model.AccountId);
                order.District = districtBLL.Details(model.DistrictId);
                //运费户头
                if (order.IsPublicDelivery)
                    order.DeliveryAccount = order.Account;
                else
                    order.DeliveryAccount = accountBLL.GetCashAccountByCustomerId(order.Customer.Id);
                if (order.DeliveryAccount == null)
                {
                    return ReState.ArgError.Create("不能找到指定的运费户头");
                }
                if (model.LockOrderId != Guid.Empty)
                    order.LockOrder = lockBLL.Details(model.LockOrderId);
                order.IsStandard = !order.Account.IsCash;
                order.CommodityInfos = new List<CommodityInfo>();
                foreach (var item in model.CommodityInfos)
                {
                    var commodityInfo = new CommodityInfo();
                    item.ToEntity(commodityInfo);
                    if (commodityInfo.Price == 0)
                        return ReState.ArgError.Create("商品价格不能为0");
                    commodityInfo.Commodity = commodityBLL.Details(item.CommodityId);
                    commodityInfo.Price = commodityInfo.Price;
                    commodityInfo.Weight = commodityInfo.Commodity.Weight;
                    commodityInfo.CalcNew();
                    order.CommodityInfos.Add(commodityInfo);
                }

                //先行判断该客户在余额表中是否存在
                if (!customerBalanceBll.IsExistAccount(model.CustomerId, ClientHelper.ClientInfo.Id))
                {
                    //判断该客户下有多少个户头
                    Customer customer = customerBLL.Details(model.CustomerId);
                    if (customer != null)
                    {
                        foreach (var item in customer.Accounts)
                        {
                            //添加账户余额
                            CustomerBalance customerBalance = new CustomerBalance();
                            customerBalance.EmployeeId = ClientHelper.ClientInfo.Id;
                            customerBalance.CustomerId = model.CustomerId;
                            customerBalance.AccountId = item.Id;
                            customerBalance.Id = Guid.NewGuid();
                            customerBalance.Balance = 0;
                            customerBalanceBll.Create(customerBalance);
                           
                        }
                    }
                }
                var result = saleSvc.Create(order);
                tran.Complete();
                return result;
            }
        }

        /// <summary>
        /// 取消计划单
        /// </summary>
        /// <param name="id">取消计划单</param>
        [Route("Cancel")]
        //[ApiUserRoleAuth(RolesConst.ClientManager, RolesConst.Admin)]
        public void Cancel(Guid id)
        {
            var emp = employeeBLL.Details(ClientHelper.ClientInfo.Id);
            var order = bll.Details(id);
            if (order.State == OrderState.Pending || order.State == OrderState.Checked)
            {
                saleSvc.Cancel(id, emp.Id);
            }
            else if (order.State == OrderState.Cancel || order.State == OrderState.Return ||
                     order.State == OrderState.End)
            {
                throw new ApiArgException("错误的订单状态");
            }
            else
            {
                order.IsApproval = true;
                order.Records.Add(new OrderRecord { CreateTime = DateTime.Now, DiscountType = DiscountType.Msg, LinkId = emp.Id.ToString(), Remarks = "[" + emp.Name + "] 提交计划单取消操作，等待审核人[" + order.Provider.Manager.Name + "]审批。" });
                saleSvc.Edit(order);
                //取消审批
                SequenceApprovalBLL.CancelOrderApproval cancelOrderBll = new SequenceApprovalBLL.CancelOrderApproval();
                cancelOrderBll.Submit(order);//取消审批
            }
        }

        /// <summary>
        /// 计划单退货
        /// </summary>
        /// <param name="id">计划单退货</param>
        [Route("ReturnGoods")]
        [ApiUserRoleAuth(RolesConst.ClientManager, RolesConst.Admin)]
        public void ReturnGoods(Guid id)
        {
            var emp = employeeBLL.Details(ClientHelper.ClientInfo.Id);
            var order = bll.Details(id);
            if (order.State == OrderState.Pending || order.State == OrderState.Checked)
            {
                ReState.ArgError.Create("驻场下单后才可申请退货");
            }
            else
            {
                order.IsApproval = true;
                order.Records.Add(new OrderRecord { CreateTime = DateTime.Now, DiscountType = DiscountType.Msg, LinkId = emp.Id.ToString(), Remarks = "[" + emp.Name + "] 提交计划单退货操作" });
                saleSvc.Edit(order);
                //退货审批
                SequenceApprovalBLL.OrderReturnApproval returnOrderBll = new SequenceApprovalBLL.OrderReturnApproval();
                returnOrderBll.Submit(order);//退货审批
            }
        }

        /// <summary>
        /// 获取去订单凭证图片名称
        /// </summary>
        /// <param name="orderId">计划单编号</param>
        /// <returns></returns>
        [Route("GetReceipt")]
        public IResultState<string[]> GetReceipt(Guid orderId)
        {
            return saleSvc.GetReceipt(orderId);
        }

        /// <summary>
        /// 计划单导出
        /// </summary>
        /// <returns></returns>
        [Route("ExpOrder")]
        [HttpGet]
        public HttpResponseMessage ExpOrder()
        {
            var data = bll.Select(null, null, new QueryInfo() { Page = 1, Rows = 19999 });
            HttpResponseMessage msg = null;

            var expData =
                data.Value.Select(
                    p =>
                        new string[]
                        {
                            p.Id.ToString(), p.Customer==null? "":p.Customer.Name, p.Creater==null?"":p.Creater.Name, 
                            p.Account==null?"":p.Account.BankName, p.Account==null?"":"(号)"+p.Account.BankNumber, 
                            p.District+"", p.Address, p.IsFullPayment?"是":"否", p.IsStandard?"是":"否", p.CreateTime.ToString(),
                            p.PaidDelivery.ToString(), p.DeliveryPrice.ToString(), p.DeliveryPriceTotal.ToString(),p.IsPublicDelivery?"是":"否",
                            p.IsDelivery?"送货":"自提", p.Contact,p.ContactPhone, p.VehicleInfos, p.Remarks, p.Provider.Name, 
                            p.Weight.ToString(), p.Total.ToString()

                        });

            var nameArray = new string[] { "id", "客户名", "客户经理", "户头银行名称", "户头银行卡号", 
                "所在地", "详细地址", "是否先款", "是否标件", "创建时间", "已缴运费", "每吨运费", "总运费", 
                "运费是否公户", "是否送货",
                "联系人", "联系人手机号", "车辆信息", "备注", "仓库名称", "重量(t)", "金额"};

            msg = CsvExp("计划单数据.csv", expData, nameArray);
            return msg;
        }

        /// <summary>
        /// 付款
        /// </summary>
        /// <param name="id">计划单编号</param>
        [Route("Payment")]
        //[ApiUserRoleAuth(RolesConst.ClientManager, RolesConst.Admin)]
        public void Payment(Guid id)
        {
            var emp = employeeBLL.Details(ClientHelper.ClientInfo.Id);
            var order = bll.Details(id);
            OrderBLL.AccountChangePayOrder(order.Account);
        }
    }
}